﻿<h3>
    Demos - Behaviors - Putting It All Together</h3>
<hr />
<p>
    Let's try a more complex example using <strong>Docs.Demos.Queueable.Toggler, Docs.Demos.Queueable.Slider,
        and Docs.Demos.Queueable.SlideToggler</strong>, reproduced below for your convenience.</p>
<h4>
    Docs.Demos.Queueable.SlideToggler</h4>
<pre>
// Docs.Queueable.Toggler :: Toggles visibility of first child elements. 
// Fires an event on toggle, and unqueues.
(function ($) {
    $.class.ns('Docs.Demos.Queueable');
    Docs.Demos.Queueable.Toggler = $.class.define(function () {
        var _context;
        var _config;
        var _toggleClass;
        var self = {
            init: function (context) {
                _context = context;
                _config = $(_context).domdata();
                _toggleClass = (_config.toggleClass ? _config.toggleClass 
                                                : "toggle-off toggle-on");
                if (_config.behaviorsEager)
                    self.toggle();
            },
            toggle: function () {
                $(_context).children().toggleClass(_toggleClass);
                $(_context).eventFire("onToggle").unqueue();
            }
        };
        return self;
    });
})(jQuery);


// Docs.Queueable.Slider :: Slides the element a specified number of 
// pixels left or right. Fires events for it's actions, and unqueues
(function ($) {
    $.class.ns('Docs.Demos.Queueable');
    Docs.Demos.Queueable.Slider = $.class.define(function () {
        var _context;
        var _data;
        var _slideDistance;
        var _slideTime;
        var self = {
            init: function (context) {
                _context = context;
                _data = $(_context).domdata();
                _slideDistance = (_data.slideDistance ? _data.slideDistance : 100);
                _slideTime = (_data.slideTime ? _data.slideTime : 1000);
            },
            slideRight: function () {
                $(_context).animate({ marginLeft: '+=' + _slideDistance + 'px' }, 
                    _slideTime, function () { $(_context).eventFire("onSlideRight").unqueue(); });
            },
            slideLeft: function () {
                $(_context).animate({ marginLeft: '-=' + _slideDistance + 'px' }, 
                    _slideTime, function () { $(_context).eventFire("onSlideLeft").unqueue(); });
            }
        };
        return self;
    });
})(jQuery);

// Docs.Demos.Queueable.SlideToggler :: Slides the element a specified number of 
// pixels left or right and then toggles the first children.
(function ($) {
    if (!Docs.Demos.Queueable.Toggler) {
        throw 'Initialization Error: Docs.Demos.Queueable.slideToggler 
            requires Docs.Demos.Queueable.Toggler';
    }
    if (!Docs.Demos.Queueable.Slider) {
        throw 'Initialization Error: Docs.Demos.Queueable.slideToggler 
            requires Docs.Demos.Queueable.Slider';
    }
    $.class.ns('Docs.Demos.Eventable');
    Docs.Demos.Queueable.SlideToggler = $.class.define(function () {
        var _context;
        var _lastSlideRight;

        var toggleElement = function () {
            $(_context).msg('toggle');
        };
        var setEvents = function () {
            $(_context).eventUnsubscribe('onSlideRight', toggleElement);
            $(_context).eventUnsubscribe('onSlideLeft', toggleElement);
            $(_context).eventSubscribe('onSlideRight', toggleElement);
            $(_context).eventSubscribe('onSlideLeft', toggleElement);
        };

        var self = {
            init: function (context) {
                _context = context;
                _lastSlideRight = false;
            },
            slideToggle: function () {
                setEvents();
                if (_lastSlideRight) {
                    $(_context).msg('slideLeft');
                    _lastSlideRight = false;
                } else {
                    $(_context).msg('slideRight');
                    _lastSlideRight = true;
                }
            }
        };
        return self;
    });
})(jQuery);</pre>
<p>
    Since this behavior only makes message calls for other behaviors and wires up events,
    it didn't need any modification to work with our new queueable versions of Toggler
    and Slider. The only change was to the namespace for it's dependencies.</p>
<p>
    The following markup demonstrates the combined effect of messaging, DOM data, combined
    behaviors, eventing, and queueing.</p>
<pre>&lt;div class=&quot;square mas&quot; data-behaviors-lazy=&quot;Docs.Demos.Queueable.Toggler 
    Docs.Demos.Queueable.Slider Docs.Demos.Queueable.SlideToggler&quot;
    data-slide-time=&quot;2000&quot; data-slide-distance=&quot;200&quot; data-toggle-class=&quot;bg-red bg-green&quot;&gt;
    &lt;div class=&quot;square bg-red pointer toggle-on&quot; 
        onclick=&quot;$(this).parent().enqueueMsg(&#39;slideToggle&#39;)
            .enqueueMsg(&#39;slideToggle&#39;).unqueue()&quot;&gt;
    &lt;/div&gt;                
&lt;/div&gt;</pre>
<p>
    Click the square below to see it in action.</p>
<div class="square mas" data-behaviors-lazy="Docs.Demos.Queueable.Toggler Docs.Demos.Queueable.Slider Docs.Demos.Queueable.SlideToggler"
    data-slide-time="2000" data-slide-distance="200" data-toggle-class="bg-red bg-green">
    <div class="square bg-red pointer toggle-on" onclick="$(this).parent().enqueueMsg('slideToggle').enqueueMsg('slideToggle').unqueue()">
    </div>
</div>
